#include"mysem.hpp"
#include<vector>
#include<unistd.h>
#include"mymutex.hpp"
#include<iostream>
using namespace my_mutex;
using namespace my_sem;
using namespace std;
template<typename T>
class RingQueue
{
public:
    RingQueue(int cap)
    :_cap(cap)
    ,_rq(cap)
    ,_psem(cap)
    ,_csem(0)
    ,_pstep(0)
    ,_cstep(0)
    {}
    void Equeue(T data)//入队列，生产者使用
    {
        _psem.P();//判断是否满了
        //生产者加锁
        _pmutex.lock();
        _rq[_pstep]=data;
        _pstep++;
        _pstep%=_cap;
        _pmutex.unlock();
        _csem.V();//唤醒消费者
    }
    T Pop()//出队列,消费者使用
    {
        _csem.P();//判断是否为空
        _cmutex.lock();
        T data=_rq[_cstep];
        _cstep++;
        _cstep%=_cap;
        _cmutex.unlock();
        _psem.V();//唤醒生产者
        return data;
    }
    ~RingQueue()
    {}
private:
    std::vector<T> _rq;
    int _cap;//环形队列的大小
    mysem _psem;//生产者的信号量
    mysem _csem;//消费者信号量
    int _pstep;//生产者的位置
    int _cstep;//消费者的位置
    //加两把锁,以满足多c多p的情况
    mymutex _pmutex;//维持生产者之间的互斥
    mymutex _cmutex;//维持消费者之间的互斥
};